package com.wq.code;

/**
 * @Author: wangqiang20995
 * @Date:2019/5/17
 * @Description:
 * @Resource:
 */
public class StringDemo {

    public static void main(String[] args) {
        System.out.println(10 & 1);
        String a = "计算机123";//常量池引用
        String b = new StringBuilder("计算机123").toString();//堆上引用
        String c = new StringBuilder("计算机").append("123").toString();//堆上引用
        System.out.println("[b.intern() == a]:" + (b.intern() == a));
        System.out.println("[c.intern() == b.intern()]:" + (c.intern() == b.intern()));
        System.out.println("[c.intern() == a]:" + (c.intern() == a));


        String s3 = new String("2") + new String("2");//创建五个对象，一个常量池中字面量2的引用对象，两个string对象，一个StringBuilder，一个默认调用StringBuilder#toString创建的对象,返回的是堆上对象
        String s4 = "22";        // 常量池中不存在22，所以会新开辟一个存储22对象的常量池地址
        String s5 = s3.intern();    // 常量池22的地址和s3的地址不同
        System.out.println("[s3 == s4]:" + (s3 == s4)); // false
        System.out.println("[s5 == s4]:" + (s5 == s4)); // true
        String d = new String("hello") + new String("bbb");//创建了三个String引用{两个显式的new，还有一个是+运算符重载，通过StringBuilder#toString创建的string}，一个StringBuilder引用，返回的是StringBuilder.append.toString之后的引用
        d.intern();
        System.out.println("[d.intern() == \"hellobbb\"]:" + (d.intern() == "hellobbb"));

//        String e2 = "hhbb";//如果实现声明这个字符串，那么是存在常量池中
        String e = new StringBuilder("hh").append("bb").toString();
        System.out.println("[e.intern() == e]:" + (e.intern() == e));//如果开启上一行的注解，那么返回的是false，e.intern()返回的其实是e2在常量池的地址，如果不打开注释，由于之前常量池中没有hhbb的字符串，所以jdk1.7返回的其实是堆上地址，是先再常量池中建立一个引用，指向了堆上的地址
        String e1 = "hhbb";//如果String e2 = "hhbb"没有打开，那么e1指向了常量池，但此时常量池中地址还是指向堆上，所以最终指向了堆上
        System.out.println("[e1 == e]:" + (e1 == e));

        String f1 = "ppp";//创建在常量池中
        String f = new StringBuilder("ppp").toString();//创建在堆上，创建了两个对象，一个是StringBuilder，一个是toString中的new String
        System.out.println("[f.intern() == f1]:" + (f.intern() == f1));//f.intern返回的是常量池中f1的地址，因为之前就已经存在了
        System.out.println("[f.intern() == f]:" + (f.intern() == f));

        String g = new String("nwerk");//创建两个对象，一个是字面量nwerk的常量池对象，一个是堆上的string对象
        String g2 = g.intern();
        String g1 = "nwerk";
        System.out.println("[g == g1]:" + (g == g1));
        System.out.println("[g2 == g1:]" + (g2 == g1));

        String hh = ("aa" + new String("bb")).intern();//返回的是字符串“aabb”在堆上的引用，即使调用了intern方法，因为常量池中之前没有aabb这个字符串，所以intern只是在常量池中新建了一个指向堆上“aabb”的指针
        String hh1 = "aabb";
        System.out.println("[hh == hh1]:" + (hh == hh1));

        String h1 = "oopp";
        String h = ("oo" + new String("pp")).intern();
        System.out.println("[h1 == h]:" + (h1 == h));

    }


}
